/*
 * Galaxium Messenger
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


using System;
using System.Collections.Generic;

using Gtk;

using WebKit;

using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

namespace Galaxium.WebKit
{
	public class WebKitHTMLWidget : WebView, IHTMLWidget
	{
		public event EventHandler Ready;
		public event EventHandler Loaded;
		public event LinkEventHandler LinkClicked;
		
		Queue<string> _jsQueue = new Queue<string> ();
		bool _navigating;
		
		public WebKitHTMLWidget ()
		{
			Realized += delegate { OnReady (); };
			NavigationRequested += delegate (object sender, NavigationRequestedArgs args)
			{
				bool navigate = true;
				
				if (!_navigating)
					navigate = OnLinkClicked (new LinkEventArgs (args.Request.Uri));
				
				args.RetVal = navigate ? NavigationResponse.Accept : NavigationResponse.Ignore;
			};
			LoadProgressChanged += delegate (object sender, LoadProgressChangedArgs args)
			{
				//Log.Debug ("Load Progress {0} (Navigating {1})", args.Progress, _navigating);
				
				if (args.Progress >= 100)
				{
					_navigating = false;
					ProcessJsQueue ();
					
					OnLoaded ();
				}
			};
		}
		
		public void LoadUrl (string url)
		{
			_navigating = true;
			base.Open (url);
		}
		
		public void LoadHtml (string html)
		{
			_navigating = true;
			base.LoadHtmlString (html, CoreUtility.DataDirectory);
		}
		
		public void RunJavaScript (string js)
		{
			_jsQueue.Enqueue (js);
			ProcessJsQueue ();
		}
		
		void ProcessJsQueue ()
		{
			if (_navigating)
				return;
			if (!IsRealized)
				return;
			
			while (_jsQueue.Count > 0)
			{
				string js = _jsQueue.Dequeue ();
				//Log.Debug ("Running JS: {0}", js);
				base.ExecuteScript (js);
			}
		}
		
		protected override void OnPopulatePopup (Menu menu)
		{
			foreach (Widget child in menu.Children)
				menu.Remove (child);
			
			ImageMenuItem item = new ImageMenuItem ("Copy");
			item.Image = new Image ("gtk-copy", IconSize.Menu);
			item.Activated += delegate { base.CopyClipboard (); };
			menu.Add (item);
			
			menu.Add (new SeparatorMenuItem ());
			
			item = new ImageMenuItem ("Select All");
			item.Image = new Image ("gtk-select-all", IconSize.Menu);
			item.Activated += delegate { base.SelectAll (); };
			menu.Add (item);
			
			menu.ShowAll ();
		}
		
		protected void OnReady ()
		{
			if (Ready != null)
				Ready (this, EventArgs.Empty);
		}
		
		protected void OnLoaded ()
		{
			if (Loaded != null)
				Loaded (this, EventArgs.Empty);
		}
		
		protected bool OnLinkClicked (LinkEventArgs args)
		{
			if (LinkClicked != null)
				return LinkClicked (this, args);
			
			return true;
		}
	}
}
